#include "Entities/BodyEntity.h"

using namespace cmn;
using namespace drawing;
using namespace editor_core;

BodyEntity::BodyEntity( float mass, float inertia, float friction, float restitution ) :
	m_mass( mass ),
	m_inertia( inertia ),
	m_friction( friction ),
	m_restitution( restitution )
{}

BodyEntity::~BodyEntity() {}

void BodyEntity::AddCircle( CircleEntity* circle ) {
	m_circles.Add( circle );
}

void BodyEntity::RemoveCircle( CircleEntity* circle ) {
	m_circles.Remove( circle );
}

void BodyEntity::GetCircles( ICollection<CircleEntity*>& circles ) const {
	circles.Clear();
	for( IteratorPtr<CircleEntity*> circlesIter( m_circles );
			!circlesIter.IsEnd();
			circlesIter.Next() )
	{
		circles.Add( circlesIter.Current() );
	}
}

void BodyEntity::AddPolygon( PolygonEntity* polygon ) {
	m_polygons.Add( polygon );
}

void BodyEntity::RemovePolygon( PolygonEntity* polygon ) {
	m_polygons.Remove( polygon );
}

void BodyEntity::GetPolygons( ICollection<PolygonEntity*>& polygons ) const {
	polygons.Clear();
	for( IteratorPtr<PolygonEntity*> polygonsIter( m_polygons );
			!polygonsIter.IsEnd();
			polygonsIter.Next() )
	{
		polygons.Add( polygonsIter.Current() );
	}
}

void BodyEntity::GetChildren( ICollection<IEntity*>& children ) const {
	children.Clear();
	for( IteratorPtr<PolygonEntity*> polygonsIter( m_polygons );
			!polygonsIter.IsEnd();
			polygonsIter.Next() )
	{
		children.Add( polygonsIter.Current() );
	}
	for( IteratorPtr<CircleEntity*> circlesIter( m_circles );
			!circlesIter.IsEnd();
			circlesIter.Next() )
	{
		children.Add( circlesIter.Current() );
	}
}

void BodyEntity::GetParents( ICollection<IEntity*>& parents ) const {
	parents.Clear();
}

void BodyEntity::GetProperties( ICollection<Property>& properties ) const {
	properties.Clear();
	properties.Add( Property( 101, "Mass", PropertyValue( m_mass ) ) );
	properties.Add( Property( 102, "Inertia", PropertyValue( m_inertia ) ) );
	properties.Add( Property( 103, "Friction", PropertyValue( m_friction ) ) );
	properties.Add( Property( 104, "Restitution", PropertyValue( m_restitution ) ) );
}

bool BodyEntity::TryUpdateProperty( Property& property ) const {
	switch( property.GetKey() ) {
		case 101:
			property.SetValue( PropertyValue( m_mass ) );
			return true;
		case 102:
			property.SetValue( PropertyValue( m_inertia ) );
			return true;
		case 103:
			property.SetValue( PropertyValue( m_friction ) );
			return true;
		case 104:
			property.SetValue( PropertyValue( m_restitution ) );
			return true;
		default:
			return false;
	}
}

bool BodyEntity::TryUpdateFromProperty( const Property& property ) {
	switch( property.GetKey() ) {
		case 101:
			m_mass = property.GetValue().GetFloat();
			return true;
		case 102:
			m_inertia = property.GetValue().GetFloat();
			return true;
		case 103:
			m_friction = property.GetValue().GetFloat();
			return true;
		case 104:
			m_restitution = property.GetValue().GetFloat();
			return true;
		default:
			return false;
	}
}

void BodyEntity::Tick() {}
void BodyEntity::DrawInner( IDrawer* drawer ) {}

void BodyEntity::Delete() {}
void BodyEntity::Undelete() {}

bool BodyEntity::Contains( const Vec2& point ) const {
	return true;
}
